#include "MatEdu.h"
#include "Wezel.h"
#include "Element.h"

using std::cout;

Matematyka::Matematyka(unsigned stopien): _stopien(stopien)
{
	_macierzKonduktancji = alokujMacierz(_stopien);
	_wektorWymuszen = alokujWektor(_stopien);
	_wynik = alokujWektor(_stopien);
}
Matematyka::~Matematyka()
{
	zwolnijMacierz(_macierzKonduktancji, _stopien);
	zwolnijWektor(_wektorWymuszen);
	zwolnijWektor(_wynik);
}
double** Matematyka::alokujMacierz(unsigned stopien)
{
	double** p; 
	try
	{
		p = new double* [stopien];
		for (unsigned i = 0; i < stopien; i++ )
			p[i] = new double[stopien];
	}
	catch (std::bad_alloc e)
	{
		cout << "Wyjatek alokacji: " << e.what() << "\n";
	}
	for(unsigned i = 0; i < stopien; i++)
		for(unsigned j = 0; j < stopien; j++)
			p[i][j] = 0;
	return p;
} 
double* Matematyka::alokujWektor(unsigned stopien)
{
	double* p;
	try
	{
		p = new double[stopien];
	}
	catch (std::bad_alloc e)
	{
		cout << "Wyjatek alokacji: " << e.what() << "\n";
	}
	for(unsigned i = 0; i < stopien; i++)
		p[i] = 0;
	return p;
}
void Matematyka::zwolnijMacierz(double** macierz, unsigned stopien)
{
	for (unsigned i = 0; i < stopien; i++)
		delete[] macierz[i];
	macierz = 0;
	delete[] macierz;
}
void Matematyka::zwolnijWektor(double* wektor)
{
	wektor = 0;
	delete[] wektor;
}
void Matematyka::gauss()
{
	double x, suma;
	int n = _stopien-1;
	if (n == 0)
	{
		std::cout << "Macierz stopnia pierwszego! Nastapi wyjscie z programu...";
		std::cin.get();
		exit(1);
	}
	for(int i = 0; i < n; i++)
		_wynik[i] = _wektorWymuszen[i];

	for (int k=0;k<n-1;k++)
	{
		for (int i=k+1;i<n;i++)
		{
			x = _macierzKonduktancji[i][k]/_macierzKonduktancji[k][k];
			for (int j=k+1;j<n;j++)
				_macierzKonduktancji[i][j] = _macierzKonduktancji[i][j] -_macierzKonduktancji[k][j]*x;
			_wynik[i] = _wynik[i] - _wynik[k]*x;
		}
	}

	_wynik[n-1]=_wynik[n-1]/_macierzKonduktancji[n-1][n-1];

	for (int i = n-2; i >= 0; i--)
	{
		suma = _wynik[i];
			for (int j = i+1; j < n; j++)
				suma = suma - _macierzKonduktancji[i][j]*_wynik[j];
		_wynik[i] = suma/_macierzKonduktancji[i][i];
	}
	_wynik[n] = 0;
}
void Matematyka::wyswietl(unsigned ile, Wyjscie& wy)
{
	for(unsigned i = 0; i < ile; i++)
	{
		for(unsigned j = 0; j < ile; j++)
		{
			wy << std::setprecision(2) << std::fixed << _macierzKonduktancji[i][j] << "\t";
		}
		wy << " | " << std::setprecision(2) << std::fixed << _wektorWymuszen[i] << "\n";
	}
}
